package code;

import heap.Tuple;

import java.io.*;
import java.util.regex.*;

import btree.Interface3;
import btree.RdbIndexType;
import tests.GetStuff;
import tests.Log;
import tests.runTest;

public class query {
	private static Log log = Log.getInstance(query.class.getName());
	Interface3 i = null;
	String queryFile = null;
	
	public query(Interface3 i3, String queryFile){
		this.i = i3;
		this.queryFile = queryFile;
		init();
	}
	
	public void init(){		
		FileInputStream fstream;
		try {
			fstream = new FileInputStream(queryFile);
			DataInputStream in = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String queryString = "";
			String temp;
			while ((temp = br.readLine()) != null)   {
				queryString = temp.trim(); 
				System.out.println (queryString);
				log.write("*************************************QUERY**************************************************");
				log.write(queryString);
				processQueryString(queryString);
			}			
			
		} catch (FileNotFoundException ex) {
			System.out.println("File not found");
		} catch (IOException ex) {
			ex.printStackTrace();
		}catch(Exception ex){
			ex.printStackTrace();
			System.out.println(ex.getMessage());

		}
	}
	public  void processQueryString(String queryString) throws Exception{

	        Pattern pattern = Pattern.compile ("(.*)\\((.*)\\((.*)\\(\\[(.*),(.*),(.*),(.*)\\],(.*),(.*),(.*),(.*),(.*),(.*),(.*),(.*),(.*)\\),(.*),(.*),(.*),(.*),(.*),(.*),(.*),(.*),(.*)\\),(.*),(.*),(.*)\\)");
	        Matcher obj = pattern.matcher(queryString); 
	        obj.find();
	        String SF1 = ("null".equals(obj.group(4)))?null:obj.group(4);
	        String PF1 = ("null".equals(obj.group(5)))?null:obj.group(5);
	        String OF1 = ("null".equals(obj.group(6)))?null:obj.group(6);
	        Float CF1 = ("null".equals(obj.group(7)))?null:new Float(obj.group(7));
	        int JNP = ("null".equals(obj.group(8)))?null:Integer.parseInt((obj.group(8)));
	        int JONO = ("null".equals(obj.group(9)))?null:Integer.parseInt((obj.group(9)));
	        String RSF = ("null".equals(obj.group(10)))?null:obj.group(10);
	        String RPF = ("null".equals(obj.group(11)))?null:obj.group(11);
	        String ROF = ("null".equals(obj.group(12)))?null:obj.group(12);
	        Float RCF = ("null".equals(obj.group(13)))?null:new Float(obj.group(13));
	        String p = ("null".equals(obj.group(14)))?null:obj.group(14).replace(':', ',');
	       
	        String LONPsss = p.substring(1, p.length()-1);
	        String[] arr1=LONPsss.split(",");
	        int LONP[] = null;
	        if (arr1 != null) {
	        		 LONP = new int[arr1.length];
	        for(int i=0;i<arr1.length;i++)
	            LONP[i] = Integer.parseInt(arr1[i]);
	        }
	        
	        int ORS = ("null".equals(obj.group(15)))?null:Integer.parseInt((obj.group(15)));
	        int ORO = ("null".equals(obj.group(16)))?null:Integer.parseInt((obj.group(16)));
	        int JNP1 = ("null".equals(obj.group(17)))?null:Integer.parseInt((obj.group(17)));
	        int JONO1 =("null".equals(obj.group(18)))?null:Integer.parseInt((obj.group(18)));
	        String RSF1 = ("null".equals(obj.group(19)))?null:obj.group(19);
	        String RPF1 = ("null".equals(obj.group(20)))?null:obj.group(20);
	        String ROF1 = ("null".equals(obj.group(21)))?null:obj.group(21);
	        Float RCF1 = ("null".equals(obj.group(22)))?null:new Float(obj.group(22));
	        String q = ("null".equals(obj.group(23)))?null:obj.group(23).replace(':', ',');
	        int LONP1[] = null;
	        String LONP1sss = q.substring(1, q.length()-1);
	        System.out.println(LONP1sss);
	        String[] arr2=LONP1sss.split(",");
	        if (arr2 != null ) {
	         LONP1 = new int[arr2.length];
	        for(int i=0;i<arr2.length;i++)
	        {
	        	System.out.println("enter for loop");
	        	System.out.println("no of left nodes projected is "+LONP.length+"ORS is "+ORS+"ORO is"+ORO);
	        		
	        		LONP1[i] = Integer.parseInt(arr2[i]);
	        		System.out.println("current LONP element is "+LONP1[i]);
        		if(LONP1[i]<= LONP.length+ORS+ORO)
	        			System.out.println("Valid LONP1");
	        		else
	    	        		throw new Exception("Please enter valid LeftoutNodePositions");
	        		}
	        
	        }
	  
	        int ORS1 = ("null".equals(obj.group(24)))?null:Integer.parseInt((obj.group(24)));
	        int ORO1 = ("null".equals(obj.group(25)))?null:Integer.parseInt((obj.group(25)));
	        int SO = ("null".equals(obj.group(26)))?null:Integer.parseInt((obj.group(26)));
	        int NP = ("null".equals(obj.group(27)))?null:Integer.parseInt((obj.group(27)));
	        int NumPages = ("null".equals(obj.group(28)))?null:Integer.parseInt((obj.group(28)));
	       
	        for (int i = 1; i <= obj.groupCount(); i++)
	        	 System.out.println(obj.group(i));
	        i.JoinSecondLevelQuery(SF1,PF1,OF1,CF1,RSF,RPF,ROF,RCF,
	        		RdbIndexType.SPO, NumPages,JNP,JONO,ORS,ORO,RSF1,RPF1,
	        		ROF1,RCF1,JNP1,JONO1,ORS1,ORO1,LONP,LONP1);
	        		
//	        i.JoinSecondLevelQuery("Jorunn_Danielsen"  //BP filter on subject
//					,null               //BP filter on predicate
//					, null              //BP filter on object
//					, (float).9         //BP filter on confidence
//					,    null           //1st LEVEL FILTER ON TRIPLE HEAP on SUBJECT
//					,null               //1st LEVEL FILTER ON TRIPLE HEAP on PREDICATE
//					,null               //1st LEVEL FILTER ON TRIPLE HEAP on OBJECT
//					, (float).1         //1st LEVEL FILTER ON TRIPLE HEAP on CONFIDENCE
//					,RdbIndexType.SPO, 10,
//						1               //join node position in BP 1st level
//						, 0             //join on subject(i.e 0) or object(i.e 1) from RHS @ 1st level
//						,0              //if want to project level 1 RHS subject put 1 else 0 
//						,0              //if want to project level 1 RHS object put 1 else 0
//						,null,  //subject filter on triple heap file 2nd level
//						"knows"   //predicate filter on triple heap file 2nd level
//						,null    //object filter on triple heap file 2nd level
//						,(float) .1   //confidence filter on triple heap file 2nd level
//						,1          //join node position in BP 2nd level
//						,0          //join on subject(i.e 0) or object(i.e 1) from RHS @ 2nd level
//						,0          //if want to project level 2 RHS subject put 1 else 0 
//						,1          //if want to project level 2 RHS object put 1 else 0 
//						, new int[]{1,2}  //projection list of left hand side BP 1st level
//					, new int[]{1,2}    //projection list of left hand side BP 2st level
//					);
			Tuple t = null;
			int num_nodes = LONP1.length+ORO1+ORS1+3;
			NP = NP==-1?num_nodes-3:NP;
			i.createTempTable(NP,num_nodes);
			
			while ((t = i.getNext()) != null) {
				i.sutil.writeBPTuple(t);
				//System.out.println("Help me! am struck");
			}
			String [] sortValue;
			System.out.println("Getting values.....");
			
			while ((sortValue = i.sutil.nextSortedBPTuple(NumPages)) != null) {
				String str ="";
				for (int i1 = 0; i1 < sortValue.length; i1++){
					System.out.print(sortValue[i1] +"   ");
					str =str + sortValue[i1] +"   ";
				}
				log.write(str);
				System.out.println();
			}
			i.destroyTempTable();
//	        i3.JoinSecondLevelQuery(SF1, PF1, OF1, CF1, RSF, RPF, ROF, RCF, SO, NumPages, JNP, JONO,ORS , ORO, RSF1, RPF1, ROF1, RCF1, JNP1, JONO1, ORS1, ORO1, LONP, LONP1);
	}
	       
	
//	public String processQueryString1(String queryString) throws Exception{
//		int sPos = queryString.indexOf("S(");
//		int jPos = queryString.indexOf("J(");
//		int closeParen;
//		String otherParams = "";
//		String heapParams = "";
//		if(sPos != -1){
//			if(jPos != -1){
//				if(sPos < jPos){	//if it contains a Sort and a Join, check which comes first
//					System.out.println("it contains a Sort and a Join");
//					System.out.println(sPos);
//					System.out.println(jPos);
//					closeParen = queryString.lastIndexOf(")");
//					if(closeParen == -1){
//						throw new Exception("No closing parenthesis");
//					}
//					queryString = queryString.substring(sPos+2, closeParen).trim();
//					if(queryString.indexOf("(") != -1 && queryString.lastIndexOf(")") != -1){
//						otherParams = queryString.substring(queryString.lastIndexOf(")")+1);
//						heapParams = queryString.substring(0,queryString.lastIndexOf(")")+1);
//					}else if(queryString.indexOf("[") != -1 && queryString.lastIndexOf("]") != -1){
//						otherParams = queryString.substring(queryString.lastIndexOf("]")+1);
//						heapParams = queryString.substring(queryString.indexOf("[")+1,queryString.lastIndexOf("]")+1);
//					}else{
//						otherParams = queryString.substring(queryString.indexOf(",")+1);
//						heapParams = queryString.substring(0, queryString.indexOf(","));
//					}
//					//System.out.println(queryString);
//					
//					
//					return runSort(processQueryString1(heapParams),otherParams);
//				}else{				//Join comes first
//					System.out.println("Join comes first");
//					closeParen = queryString.lastIndexOf(")");
//					if(closeParen == -1){
//						throw new Exception("No closing parenthesis");
//					}
//					queryString = queryString.substring(jPos+2, closeParen).trim();
//					if(queryString.indexOf("(") != -1 && queryString.lastIndexOf(")") != -1){
//						otherParams = queryString.substring(queryString.lastIndexOf(")")+1);
//						heapParams = queryString.substring(0,queryString.lastIndexOf(")")+1);
//					}else if(queryString.indexOf("[") != -1 && queryString.lastIndexOf("]") != -1){
//						otherParams = queryString.substring(queryString.lastIndexOf("]")+1);
//						heapParams = queryString.substring(queryString.indexOf("[")+1,queryString.lastIndexOf("]")+1);
//					}else{
//						otherParams = queryString.substring(queryString.indexOf(",")+1);
//						heapParams = queryString.substring(0, queryString.indexOf(","));
//					}
//					//System.out.println(queryString);
//					return runJoin(processQueryString1(heapParams), otherParams);
//				}
//			}else{	//no Join, but there is a Sort
//				System.out.println("no Join, but there is a Sort");
//				closeParen = queryString.lastIndexOf(")");
//				if(closeParen == -1){
//					throw new Exception("No closing parenthesis");
//				}
//				queryString = queryString.substring(sPos+2, closeParen).trim();
//				if(queryString.indexOf("(") != -1 && queryString.lastIndexOf(")") != -1){
//					otherParams = queryString.substring(queryString.lastIndexOf(")")+1);
//					heapParams = queryString.substring(0,queryString.lastIndexOf(")")+1);
//				}else if(queryString.indexOf("[") != -1 && queryString.lastIndexOf("]") != -1){
//					otherParams = queryString.substring(queryString.lastIndexOf("]")+1);
//					heapParams = queryString.substring(queryString.indexOf("[")+1,queryString.lastIndexOf("]"));
//				}else{
//					otherParams = queryString.substring(queryString.indexOf(",")+1);
//					heapParams = queryString.substring(0, queryString.indexOf(","));
//				}
//				//System.out.println(queryString);
//				return runSort(processQueryString(heapParams), otherParams);
//			}
//		}else if(jPos != -1 && sPos== -1){	//no Sort, but there is a Join
//			System.out.println("no Sort, but there is a Join");
//			System.out.println(sPos);
//			System.out.println(jPos);
//			closeParen = queryString.lastIndexOf(")");
//			if(closeParen == -1){
//				throw new Exception("No closing parenthesis");
//			}
//			queryString = queryString.substring(jPos+2, closeParen).trim();
//			if(queryString.indexOf("(") != -1 && queryString.lastIndexOf(")") != -1){
//				otherParams = queryString.substring(queryString.lastIndexOf(")")+1);
//				heapParams = queryString.substring(0,queryString.lastIndexOf(")")+1);
//			}else if(queryString.indexOf("[") != -1 && queryString.lastIndexOf("]") != -1){
//				otherParams = queryString.substring(queryString.lastIndexOf("]")+1);
//				heapParams = queryString.substring(queryString.indexOf("[")+1,queryString.lastIndexOf("]"));
//			}else{
//				otherParams = queryString.substring(queryString.indexOf(",")+1);
//				heapParams = queryString.substring(0, queryString.indexOf(","));
//			}
//			//System.out.println(queryString);
//			
//			return runJoin(processQueryString(heapParams), otherParams);
//		}else{ //Just the heap info
//			return queryString;
//		}
//	}
//	
//	public String runJoin(String heap, String params){
//		System.out.println("Join");
//		//TODO: BP Triple Join( int amt of mem, int num left nodes, BPIterator left itr, int BPJoinNodePosition, int JoinOnSubjectorObject, java.lang.String	RightSubjectFilter, java.lang.String RightPredicateFilter, java.lang.String	RightObjectFilter, double RightConfidenceFilter, int [] LeftOutNodePositions, int OutputRightSubject, int OutputRightObject)
//		String[] paramsArray = new String[8];
//		int currentComma = params.indexOf(",");
//		int nextComma = params.indexOf(",", currentComma+1);
//		int count = 0;
//		while(nextComma != -1){
//			paramsArray[count] = params.substring(currentComma+1,nextComma).trim();
//			currentComma = nextComma;
//			nextComma = params.indexOf(",", currentComma+1);
//			count++;
//		}
//		paramsArray[7] = params.substring(currentComma+1).trim();
//		return heap + "two heaps joined";
//	}
//	
//	public String runSort(String heap, String params){
//		System.out.println("Sort");
//		//TODO: BPSort( BPIterator input_itr, BPOrder sort_order,int SortNodeIDPos,int n_pages)
//		int currentComma = params.indexOf(",");
//		int nextComma = params.indexOf(",", currentComma+1);
//		String sort_order = params.substring(currentComma+1,nextComma).trim();
//		currentComma = nextComma;
//		nextComma = params.indexOf(",", currentComma+1);
//		int SortNodeIDPos = Integer.getInteger(params.substring(currentComma+1,nextComma).trim());
//		currentComma = nextComma;
//		int n_pages = Integer.getInteger(params.substring(currentComma+1).trim());
//		System.out.println(sort_order);
//		System.out.println(SortNodeIDPos);
//		System.out.println(n_pages);
//		return heap + "one heap sorted";
//		
//		
//	}
	
	/**
	 * @param args
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		// TODO do something with args
		//System.out.println(args[0]);
		//String rdfDBName = args[0];
		//String numBuf = args[2];
		System.out.println("Please enter rdfDBName");
		String rdfDBName = GetStuff.getStrChoice();
		System.out.println("enter num of buffers");
		int numBuf = GetStuff.getIntChoice();
		System.out.println("Enter the query file name");
		String filename =GetStuff.getStrChoice(); 
		String queryfile="//home//archana//dbi-rdf//DBI_phase2//src//tests//"+filename;
		Interface3 i = new Interface3();
		i.superinit("test", 5, 20);
		i.init("test", 5, 20);
		
		FileInputStream fstream;
		try {
			fstream = new FileInputStream(queryfile);
			DataInputStream in = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String queryString = "";
			String temp;
			String file="//home//archana//dbi-rdf//DBI_phase2//src//tests//"+filename;
			query theQuery = new query(i, file);
			while ((temp = br.readLine()) != null)   {
				queryString = temp.trim(); 
				System.out.println (queryString);
				theQuery.processQueryString(queryString);
			}			
			
			//String parsingOutput = theQuery.processQueryString(queryString);
			//System.out.println("Output from parser: " + parsingOutput);
		} catch (FileNotFoundException ex) {
			System.out.println("File not found");
		} catch (IOException ex) {
			ex.printStackTrace();
		}catch(Exception ex){
			System.out.println(ex.getMessage());

		}

	}

}
//S(J(J(["dexxter","knows",null,null],1,0,null,null,0.5,{1:3},0,1),1,0,null,null,0.5,{1:3},0,1),1,3,5)
//S(J(J(["Jorunn_Danielsen","knows",null,null],3,0,null,"locates",null,null,{1:3},1,1),2,0,null,"type","Person",null,{1:2:4},1,1),0,1,5)
//S(J(J([null,"nick",null,null],3,1,null,"nick",null,null,{1:3},1,1),1,0,null,"surname",null,null,{1:3:4},1,1),0,1,5)
//S(J(J(["Jorunn_Danielsen","secondName",null,null],1,0,null,"firstName",null,null,{1:3},1,1),1,0,null,"type","Person",null,{1:2:4},1,1)0,1,5)
//S(J(J(["Jorunn_Danielsen","knows",null,null],3,0,null,"type","Person",null,{1:3},1,1)1,0,null,"title",null,null,{1,2,4},1,1),0,1,5)
//S(J(J(["Jorunn_Danielsen","secondName",null,null],1,0,null,"firstName",null,null,{1:3},1,1),1,0,null,"type","Person",null,{1:2:4},1,1)0,1,5)
//S(J(J([null,"knows","Jorunn_Danielsen",null],3,0,null,"type","Person",null,{1:3},1,1),1,0,null,"title",null,null,{1,2,4},1,1),0,1,5)
